# -*-coding:utf-8-*-

# smoothed PSSM
# http://www.nohup.cc/article/162/ 进行修改
import numpy as np
import fileinput
from typing import Union, List

# smooth - window
# 值，要求是奇数。
# 截取的序列长度，一般为25，30, 50。本例为30.

def pssm_smth(PSSM_orig, PSSM_smth, w_smth, l):
    for i in range(l):
        if i < (w_smth - 1) / 2:
            for j in range(i + int((w_smth - 1) / 2) + 1):
                PSSM_smth[i] += PSSM_orig[j]
        elif i >= (l - (w_smth - 1) / 2):
            for j in range(int(i - (w_smth - 1) / 2), l):
                PSSM_smth[i] += PSSM_orig[j]
        else:
            for j in range(int(i - (w_smth - 1) / 2), int(i + (w_smth - 1) / 2 + 1)):
                PSSM_smth[i] += PSSM_orig[j]
    return PSSM_smth


def SPSSM(
        fi: str,
        w_smth: int,
        n: int,
) -> List:
    '''
    计算smooth SPSSM
    :param fi: string pssm文件地址
    :param w_smth: int 滑动窗口，需要为奇数
    :param n: int 截取阅读框长度
    :return: List n*20维度
    '''
    PSSM = []
    seq_cn = 0
    for line, strin in enumerate(fileinput.input(fi)):
        if line > 2:
            str_vec = strin.split()[1:22]
            if len(str_vec) == 0:
                break
            PSSM.append(list(int(i) for i in str_vec[1:]))
            seq_cn += 1
    fileinput.close()
    PSSM_smth = np.array([[0.0] * 20] * seq_cn)
    PSSM_orig = np.array(PSSM)
    PSSM_smth_full = pssm_smth(PSSM_orig, PSSM_smth, w_smth, seq_cn)
    PSSM_smth_final = [[0.0] * 20] * n
    for i in range(n):
        PSSM_smth_final[i] = PSSM_smth_full[i]
    PSSM_smth_final_shp = np.shape(PSSM_smth_final)
    encodings = [np.reshape(PSSM_smth_final, (PSSM_smth_final_shp[0] * PSSM_smth_final_shp[1],)).tolist()]
    return encodings


if __name__ == '__main__':
    fi = 'testdata/1dp.pssm'
    result = SPSSM(fi, 30, 5)
    print(result)
